/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * SimulationCanvasPanel.java
 *
 * Created on 9 Ιουλ 2009, 12:12:50 μμ
 */

package gui;

import utilities.DrawingBean;
import simulation.GUIOptionManager;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.util.Vector;

/**
 * The canvas used to graphically present the simulation process
 * @author Arvanitis Ioannis
 */
public class SimulationCanvasPanel extends javax.swing.JPanel{
    private static int cell_width, cell_height;
    private static int w, h;
    private static int obst_cell_w, obst_cell_h;
    private static Vector<DrawingBean> obstacles_v = new Vector<DrawingBean>();
    private static Vector<DrawingBean> nodes_v = new Vector<DrawingBean>();
    private static boolean categoriesShown;

    /**
     * Sets the width of canvas in meters
     * @param width Width of canvas in meters
     */
    public static void setW(int w) {
        SimulationCanvasPanel.w = w;
    }

    /**
     * Gets the width of canvas in meters
     * @return the width of canvas in meters
     */
    public static int getW() {
        return w;
    }

    /**
     * Sets the height of canvas in meters
     * @param h Height of canvas in meters
     */
    public static void setH(int h) {
        SimulationCanvasPanel.h = h;
    }

    /**
     * Gets the height of canvas in meters
     * @return the height of canvas in meters
     */
    public static int getH() {
        return h;
    }

    /**
     * Gets the width of each cell in canvas
     * @return the width of each cell in canvas
     */
    public static int getCell_width() {
        return cell_width;
    }

    /**
     * Gets the height of each cell in canvas
     * @return the height of each cell in canvas
     */
    public static int getCell_height() {
        return cell_height;
    }

    /**
     * Gets the height of each cell in canvas for obstacles
     * @return the height of each cell in canvas for obstacles
     */
    public static int getObst_cell_h() {
        return obst_cell_h;
    }

    /**
     * Sets the height of each cell in canvas for obstacles
     * @param cell_height The height of each cell in canvas for obstacles
     */
    public static void setObst_cell_h(int obst_cell_h) {
        SimulationCanvasPanel.obst_cell_h = obst_cell_h;
    }

    /**
     * Gets the width of each cell in canvas for obstacles
     * @return the width of each cell in canvas for obstacles
     */
    public static int getObst_cell_w() {
        return obst_cell_w;
    }

    /**
     * Sets the width of each cell in canvas for obstacles
     * @param cell_width The width of each cell in canvas for obstacles
     */
    public static void setObst_cell_w(int obst_cell_w) {
        SimulationCanvasPanel.obst_cell_w = obst_cell_w;
    }

    /**
     * Determines whether categories will be indicated
     * @return whether categories will be indicated
     */
    public static boolean isCategoriesShown() {
        return categoriesShown;
    }

    /**
     * Sets whether categories will be indicated
     * @param categoriesShown whether categories will be indicated
     */
    public static void setCategoriesShown(boolean categoriesShown) {
        SimulationCanvasPanel.categoriesShown = categoriesShown;
    }





    /**
     * Creates new form SimulationCanvasPanel
     * @param w Width (in cells) of canvas
     * @param h Height (in cells) of canvas
     */
    public SimulationCanvasPanel(int w, int h) {
        setW(w);
        setH(h);
        obstacles_v = GUIOptionManager.getObstacles();
        nodes_v = GUIOptionManager.getNodes();
        setSize(800,800*h/w);
        setBackground(Color.WHITE);
        if (obstacles_v != null) {
            setObst_cell_w(GUIOptionManager.getMapWidthObstacles());
            setObst_cell_h(GUIOptionManager.getMapHeightObstacles());
        }
    }

   
    @Override
    @SuppressWarnings({"static-access", "empty-statement"})
    public void paintComponent(Graphics g) {
		super.paintComponent(g);

        if (obstacles_v != null) {
            cell_width = getWidth() / obst_cell_w;
            cell_height = getHeight() / obst_cell_h;
        }

        //paint the nodes
        for (int i=0; i<nodes_v.size(); i++) {
            g.setColor(nodes_v.get(i).getColor());
            int x, y, size;
            if (obstacles_v == null) {
                x = Math.round(((float)nodes_v.get(i).getPoint().x)/getW()*getWidth());
                y = Math.round(((float)nodes_v.get(i).getPoint().y)/getH()*getHeight());
                size = (getWidth() > getHeight())?getHeight()/50:getWidth()/50;
            }
            else {
                x = Math.round(((float)nodes_v.get(i).getPoint().x)/getW()*obst_cell_w*cell_width);
                y = Math.round(((float)nodes_v.get(i).getPoint().y)/getH()*obst_cell_h*cell_height);
                size = (obst_cell_w*cell_width > obst_cell_h*cell_height)?obst_cell_h*cell_height/50:obst_cell_w*cell_width/50;
            }
            g.fillOval(x-size/2, y-size/2, size, size);
            if (categoriesShown) {
                g.setColor(Color.DARK_GRAY);
                g.drawString(nodes_v.get(i).getInfo(), x, y);
            }
        }

        //paint the obstacles if any
        if (obstacles_v != null) {
            for (int i=0; i<obstacles_v.size(); i++) {
                g.setColor(obstacles_v.get(i).getColor());
                g.fillRect(obstacles_v.get(i).getPoint().x*cell_width, obstacles_v.get(i).getPoint().y*cell_height, cell_width, cell_height);
            }
            //paint the borders
            g.setColor(Color.LIGHT_GRAY);
            g.fillRect(obst_cell_w*cell_width, 0, obst_cell_w*cell_width, getHeight());
            g.fillRect(0, obst_cell_h*cell_height, getWidth(), obst_cell_h*cell_height);
        }
        
    }



    /**
     * Finds the current position in a grid om meters
     * @param p Given point indicating the distance from the upper left corner
     * @return the current position in a grid om meters
     */
    public Point findCurrentPosition(Point p) {
        if (obstacles_v != null) {
            return (new Point(w*p.x/(obst_cell_w*getCell_width()), h*p.y/(obst_cell_h*getCell_height())));
        }
        else {
            return (new Point(w*p.x/getWidth() , h*p.y/getHeight()));
        }
    }

    /**
     * Determines whether a given pixel is contained or not in a specified area
     * @param p Given point indicating the distance from the upper left corner
     * @return whether or not this point is located in the defined canvas
     */
    public boolean inCanvas(Point p) {
        if (obstacles_v != null) {
            if (p.x < obst_cell_w*getCell_width() && p.y < obst_cell_h*getCell_height()) {
                return true;
            }
            else {
                return false;
            }
        }
        else {
            return true;
        }
    }

    /**
     * Finds the current node indicated in the area of p
     * @param p Point indicating the area of search
     * @return the current node indicated in the area of p
     */
    public int findCurrentNode(Point p) {
        int nodeId = 0;
        double minDist = w*h;
        for (int i=0; i<nodes_v.size(); i++) {
            Point tempp = nodes_v.get(i).getPoint();
            if (Math.pow(tempp.x-p.x,2)+Math.pow(tempp.y-p.y,2) < minDist) {
                minDist = Math.pow(tempp.x-p.x,2)+Math.pow(tempp.y-p.y,2);
                nodeId = i+1;
            }
        }
        if (Math.sqrt(minDist) > 5) {
            nodeId = 0;
        }
        return nodeId;
    }








    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 400, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 300, Short.MAX_VALUE)
        );
    }// </editor-fold>//GEN-END:initComponents

    

    




    // Variables declaration - do not modify//GEN-BEGIN:variables
    // End of variables declaration//GEN-END:variables

}
